package com.demo.common;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URL;

/**
 * 字符串工具类
 * 
 * @author ryuu.kk
 */
public final class StringUtils {

	// private class
	private StringUtils() {
	}

	/**
	 * Check that the given CharSequence is neither <code>null</code> nor of
	 * length 0. Note: Will return <code>true</code> for a CharSequence that
	 * purely consists of whitespace.
	 * <p>
	 * 
	 * <pre>
	 * StringUtils.hasLength(null) = false
	 * StringUtils.hasLength("") = false
	 * StringUtils.hasLength(" ") = true
	 * StringUtils.hasLength("Hello") = true
	 * </pre>
	 * 
	 * @param str
	 *            the CharSequence to check (may be <code>null</code>)
	 * @return <code>true</code> if the CharSequence is not null and has length
	 * @see #hasText(String)
	 */
	public static boolean hasLength(CharSequence str) {
		return (str != null && str.length() > 0);
	}

	/**
	 * Check whether the given CharSequence has actual text.
	 * More specifically, returns <code>true</code> if the string not <code>null</code>,
	 * its length is greater than 0, and it contains at least one non-whitespace character.
	 * <p><pre>
	 * StringUtils.hasText(null) = false
	 * StringUtils.hasText("") = false
	 * StringUtils.hasText(" ") = false
	 * StringUtils.hasText("12345") = true
	 * StringUtils.hasText(" 12345 ") = true
	 * </pre>
	 * @param str the CharSequence to check (may be <code>null</code>)
	 * @return <code>true</code> if the CharSequence is not <code>null</code>,
	 * its length is greater than 0, and it does not contain whitespace only
	 * @see java.lang.Character#isWhitespace
	 */
	public static boolean hasText(CharSequence str) {
		if (!hasLength(str)) {
			return false;
		}
		int strLen = str.length();
		for (int i = 0; i < strLen; i++) {
			if (!Character.isWhitespace(str.charAt(i))) {
				return true;
			}
		}
		return false;
	}
	
	/**
	 * Check whether the given String has actual text.
	 * More specifically, returns <code>true</code> if the string not <code>null</code>,
	 * its length is greater than 0, and it contains at least one non-whitespace character.
	 * @param str the String to check (may be <code>null</code>)
	 * @return <code>true</code> if the String is not <code>null</code>, its length is
	 * greater than 0, and it does not contain whitespace only
	 * @see #hasText(CharSequence)
	 */
	public static boolean hasText(String str) {
		return hasText((CharSequence) str);
	}
	
	/**
	 * 从参数字符串中去除前后空格
	 * 
	 * @param str
	 *            需要去除空格的参数字符串
	 * @return 处理后的字符串
	 * @see java.lang.Character#isWhitespace
	 */
	public static String trimWhitespace(String str) {
		if (!hasLength(str)) {
			return str;
		}
		StringBuilder sb = new StringBuilder(str);
		while (sb.length() > 0 && Character.isWhitespace(sb.charAt(0))) {
			sb.deleteCharAt(0);
		}
		while (sb.length() > 0
				&& Character.isWhitespace(sb.charAt(sb.length() - 1))) {
			sb.deleteCharAt(sb.length() - 1);
		}
		return sb.toString();
	}

	/**
	 * 从参数字符串中去除所有空格 Trim <i>all</i> whitespace from the given String: leading,
	 * trailing, and inbetween characters.
	 * 
	 * @param str
	 *            要去除空格的参数字符串
	 * @return 处理后的字符串
	 * @see java.lang.Character#isWhitespace
	 */
	public static String trimAllWhitespace(String str) {
		if (!hasLength(str)) {
			return str;
		}
		StringBuilder sb = new StringBuilder(str);
		int index = 0;
		while (sb.length() > index) {
			if (Character.isWhitespace(sb.charAt(index))) {
				sb.deleteCharAt(index);
			} else {
				index++;
			}
		}
		return sb.toString();
	}

	/**
	 * 判断是否是空字符串
	 * 
	 * @param str
	 * @return
	 */
	public static boolean isEmpty(String str) {
		str = StringUtils.trimWhitespace(str);
		if (!hasLength(str)) {
			return true;
		}
		return false;
	}

	/**
	 * 判断是否是空字符串
	 * 
	 * @param str
	 * @return boolean
	 */
	public static boolean isNotEmpty(String str) {
		str = StringUtils.trimWhitespace(str);
		if (hasLength(str)) {
			return true;
		}
		return false;
	}

	/**
	 * 判断字符串是否是数字
	 * 
	 * @param str
	 *            输入
	 * @return boolean
	 */
	public static boolean isNumber(String str) {
		return str.matches("^[-+]?(([0-9]+)([.]([0-9]+))?|([.]([0-9]+))?)$");
	}

	/**
	 * 读取Text文件
	 * 
	 * @param uri
	 *            URI
	 * @return StringBuffer
	 */
	public static StringBuffer textReader(URI uri) {
		StringBuffer sb = null;

		InputStreamReader reader = null;
		InputStream is = null;
		URL url;
		try {
			url = uri.toURL();
			is = url.openStream();
			reader = new InputStreamReader(is);
			int tempchar;
			sb = new StringBuffer();
			while ((tempchar = reader.read()) != -1) {
				// 对于windows下，\r\n这两个字符在一起时，表示一个换行。
				// 但如果这两个字符分开显示时，会换两次行。
				// 因此，屏蔽掉\r，或者屏蔽\n。否则，将会多出很多空行。
				if (((char) tempchar) != '\r') {
					sb.append((char) tempchar);
				}
			}
		} catch (MalformedURLException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			if (reader != null) {
				try {
					reader.close();
				} catch (IOException e) {
				}
			}
			if (is != null) {
				try {
					is.close();
				} catch (IOException e) {
				}
			}
		}
		return sb;
	}

	/**
	 * 字符串文件写入
	 * 
	 * @param sb
	 *            字符串缓存
	 * @param url
	 *            写入路径
	 * @param apply
	 *            0 新建、1其后写入、2不存在则新建,存在则继续写入
	 * @return boolean 是否写入成功
	 * @throws IOException
	 */
	public static boolean textWriter(StringBuffer sb, URI uri, int apply)
			throws IOException {
		if (sb == null || sb.length() == 0) {
			return false;
		}
		String path = uri.getPath();
		// String name = path.substring(path.lastIndexOf("/") + 1 );
		path = path.substring(0, path.lastIndexOf("/"));
		// 写入成功标志
		boolean isSuccess = true;

		if (apply < 0 || apply > 2) {
			apply = 2;
		}
		File file = new File(uri.getPath());
		switch (apply) {
		case 0:
			if (file.exists()) {
				file.delete();
			}
			// 创建文件夹
			(new File(path)).mkdirs();
			file.createNewFile();

			break;
		case 1:
			if (!file.exists()) {
				throw new java.io.FileNotFoundException(file.getPath());
			}
			break;
		default:
			if (!file.exists()) {
				// 创建文件夹
				(new File(path)).mkdirs();
				file.createNewFile();
			}
		}
		// InputStream is = url.openStream();
		// BufferedReader reader = new BufferedReader(new
		// InputStreamReader(is));
		// String line; // 用来保存每行读取的内容
		// while((line = reader.readLine()) != null ) {
		//
		// }
		FileOutputStream os = null;
		try {
			os = new FileOutputStream(file);
			os.write(sb.toString().getBytes());
		} catch (Exception e) {
			isSuccess = false;
		} finally {
			try {
				if (os != null) {
					os.flush();
				}
			} catch (Exception e) {
			}
			try {
				if (os != null) {
					os.close();
				}
			} catch (Exception e) {
			}
		}

		return isSuccess;
	}

	/**
	 * Replace all occurences of a substring within a string with another
	 * string.
	 * 
	 * @param inString
	 *            String to examine
	 * @param oldPattern
	 *            String to replace
	 * @param newPattern
	 *            String to insert
	 * @return a String with the replacements
	 */
	public static String replace(String inString, String oldPattern,
			String newPattern) {
		if (!hasLength(inString) || !hasLength(oldPattern)
				|| newPattern == null) {
			return inString;
		}
		StringBuilder sb = new StringBuilder();
		int pos = 0; // our position in the old string
		int index = inString.indexOf(oldPattern);
		// the index of an occurrence we've found, or -1
		int patLen = oldPattern.length();
		while (index >= 0) {
			sb.append(inString.substring(pos, index));
			sb.append(newPattern);
			pos = index + patLen;
			index = inString.indexOf(oldPattern, pos);
		}
		sb.append(inString.substring(pos));
		// remember to append any characters to the right of a match
		return sb.toString();
	}

	/**
	 * 该方法用于：截取字符串 使用技巧：
	 * 假如要截取长度相当于10个中文汉字的字符串，超出用".."显示，调用subString(str,19,"..");
	 * 如果调用subString(str,20,"..")，遇到包含奇数个单字节字符如a/b/c/d的情况下，将会多截一个字；
	 * 
	 * @param content 输入内容
	 * @param toCount 字节数 a--1字节，中文汉字--2字节,(汉字数*2-1)
	 * @param more 填充内容
	 * @return 剪切后的字符串
	 */
	public static String subString(String content, int toCount, String more, String charset) {

		String cutStr = "";
		if (StringUtils.isEmpty(content)) {
			return "";
		}
		try {
			byte[] bytes = content.getBytes(charset);
			int n = 0; // 表示当前的字节数
			int i = 2; // 要截取的字节数，从第3个字节开始
			for (; i < bytes.length && n <= toCount; i++) {
				if (i % 2 == 1) {
					n++; // 在UCS2第二个字节时n加1
				} else {
					// 当UCS2编码的第一个字节不等于0时，该UCS2字符为汉字，一个汉字算两个字节
					if (bytes[i] != 0) {
						n++;
					}
				}
			}
			// 如果i为奇数时，处理成偶数
			if (i % 2 == 1) {
				// 该UCS2字符是汉字时，去掉这个截一半的汉字
				if (bytes[i - 1] != 0) {
					i = i - 1;
				} else {
					// 该UCS2字符是字母或数字，则保留该字符
					i = i + 1;
				}
			}
			cutStr = new String(bytes, 0, i, charset);
			if (toCount < bytes.length - 2) {
				cutStr += more;
			}
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		}
		return cutStr;
	}
}
